package com.hsmpay.mobile.util.icc;

public class ME30DataDecode {
    //主密钥
    public static final String MainKey = "11111111111111111111111111111111";
    // pin Key
    public static final String EncodePinKey = "D2CEEE5C1D3AFBAF00374E0CC1526C86";
    // pin Key
    //private String DecodePinKey = "2A288F61348FEE93FE9C0FC714BCDD73";

    //
    public static final String EncodeTrackKey = "63720E163236BD25165E1F34A846AB96";
    //"DBFE96D0A5F09D24DBFE96D0A5F09D24";
    //
    //private String DecodeTrackKey = "4DE5E8B8A9DCDDF94DE5E8B8A9DCDDF9";

    // ANSI X9.8
    public static byte[] getPanInfo(String pan) {
        String block0 = "0000000000000";
        int panLen = pan.length();
        byte[] panInfo = new byte[8];
        byte[] subInfo;
        panInfo[0] = 0x00;
        panInfo[1] = 0x00;
        //
        if (panLen < 13) {
            pan = block0.substring(0, 13 - panLen) + pan;
            subInfo = ByteUtil.hex2Bin(pan.substring(0, panLen - 1));
        } else {
            subInfo = ByteUtil.hex2Bin(pan.substring(panLen - 13, panLen - 1));
        }
        System.arraycopy(subInfo, 0, panInfo, 2, 6);
        return panInfo;
    }

    public static byte[] getPinBlock(String pin) {
        String block0 = "000000000000";
        String blockF = "FFFFFFFFFFFF";
        int pinLen = pin.length();
        byte[] pinInfo = new byte[8];
        byte[] subInfo;

        // Byte 2 �C Byte 3/4/5/6/7 4--12��PIN(ÿ��PINռ4��BIT)
        if (pinLen < 4) {
            pin = block0.substring(0, 4 - pinLen) + pin;
        } else if (pinLen > 12) {
            pin = pin.substring(0, 12);
        } else if (pinLen % 2 != 0) {
            pin = pin + "F";
        }
        pinLen = pin.length();
        pinInfo[0] = (byte) pinLen;
        subInfo = ByteUtil.hex2Bin(pin + blockF.substring(0, 14 - pinLen));
        System.arraycopy(subInfo, 0, pinInfo, 1, 7);
        return pinInfo;
    }

    public static String decodePinData(String key, String data, String pan) {
        DESKey desKey = new DESKey(ByteUtil.hex2Bin(key));
        byte[] pinData = DESUtil.tripleDESDecrypt(desKey, ByteUtil.hex2Bin(data));
        byte[] panData = getPanInfo(pan);
        System.out.println("3des decode data: " + ByteUtil.toHexString(pinData));
        for (int i = 0; i < 8; i++) {
            pinData[i] = (byte) (pinData[i] ^ panData[i]);
        }
        int pinLen = pinData[0];
        return ByteUtil.toHexString(pinData).substring(2, 2 + pinLen);
    }

    public static String getTDB(String data) {
        String tdbInfo;
        int dataLen = data.length();
        if (dataLen % 2 != 0)
            tdbInfo = data.substring(dataLen - 17, dataLen - 1);
        else
            tdbInfo = data.substring(dataLen - 18, dataLen - 2);
        return tdbInfo;
    }

    public static String decodeTrackData(String key, String encodeData) {
        String tdbInfo = getTDB(encodeData);
        DESKey desKey = new DESKey(ByteUtil.hex2Bin(key));
        int trackLen = encodeData.length();
        String trackData;
        if (trackLen % 2 != 0) {
            trackData = encodeData.substring(0, trackLen - 17) + ByteUtil.toHexString(DESUtil.tripleDESDecrypt(desKey, ByteUtil.hex2Bin(tdbInfo))).replace('D', '=') + encodeData.substring(trackLen - 1);
        } else {
            trackData = encodeData.substring(0, trackLen - 18) + ByteUtil.toHexString(DESUtil.tripleDESDecrypt(desKey, ByteUtil.hex2Bin(tdbInfo))).replace('D', '=') + encodeData.substring(trackLen - 2);
        }
        return trackData;
    }

    public static byte[] getDecodeKey(String key, String encodeKey) {
        DESKey desKey = new DESKey(ByteUtil.hex2Bin(key));
        byte[] decodeKey = DESUtil.tripleDESDecrypt(desKey, ByteUtil.hex2Bin(encodeKey));
        return decodeKey;
    }

    /**
     * 新大陆
     * 解密2磁道数据
     *
     * @param trace2
     * @return
     */
    public static String decryptTrace2(String trace2) {
        String DecodeTrackKey = ByteUtil.toHexString(ME30DataDecode.getDecodeKey(ME30DataDecode.MainKey, ME30DataDecode.EncodeTrackKey));
        //String EncodeTrack2Data="6217730700097783=2301E498AB0AC2F9ADA0";
        String DecodeTrack2Data = ME30DataDecode.decodeTrackData(DecodeTrackKey, trace2);
        System.out.println("decode track244444444444444 data: " + DecodeTrack2Data);
        return DecodeTrack2Data;
    }

    /**
     * 艾创 二磁道解密
     *
     * @param redom
     * @return [0] 2磁道  [1] 3磁道
     */
    public static String[] decryptTrace2_aic(String redom, String trace) {
        String tackKey = "3F9E84CAC9A53156081F4ADE12E4CAF1";//磁道密钥
        String result[] = {"", ""};
        String trackData = "";

        //获得 密钥前八位   用磁道密钥对8字节随机数进行加密，加密的结果作为密钥的左8字节。
        DESKey desKey = new DESKey(ByteUtil.hex2Bin(tackKey));
        String keyP8 = ByteUtil.toHexString(DESUtil.tripleDESEncrypt(desKey, ByteUtil.hex2Bin(redom)));
        //System.out.println(keyP8);

        //后八位 异或FFFFFFFFFFFFFFFF  然后用磁道秘钥加密
        String ff = "FFFFFFFFFFFFFFFF";//
        String yhss = ByteUtil.toHexString(XORContent(ByteUtil.hex2Bin(redom), ByteUtil.hex2Bin(ff)));
        String keyA8 = ByteUtil.toHexString(DESUtil.tripleDESEncrypt(desKey, ByteUtil.hex2Bin(yhss)));
        //System.out.println(keyA8);

        String key = keyP8 + keyA8;//组装密钥
        //System.out.println("key:"+key);

        trackData = ByteUtil.toHexString(ME30DataDecode.getDecodeKey(key, trace));

        trackData = trackData.toLowerCase();//将F去掉  并将D转成小写
        System.out.println(trackData);//磁道数据 打印
        result[0] = trackData.substring(0, 48).replaceAll("f", "");
        if (trackData.length() > 48)
            result[1] = trackData.substring(49).replaceAll("f", "");
        return result;
    }

    public static String decryptBt55_aic(String redom, String bit5) throws Exception {
        String tackKey = "3F9E84CAC9A53156081F4ADE12E4CAF1";//磁道密钥

        //获得 密钥前八位   用磁道密钥对8字节随机数进行加密，加密的结果作为密钥的左8字节。
        DESKey desKey = new DESKey(ByteUtil.hex2Bin(tackKey));
//		String keyP8 = ByteUtil.toHexString(DESUtil.tripleDESEncrypt(desKey, ByteUtil.hex2Bin(redom)));
//		//System.out.println(keyP8);
//		
//		//后八位 异或FFFFFFFFFFFFFFFF  然后用磁道秘钥加密
//		String ff = "FFFFFFFFFFFFFFFF";//
//		String yhss = ByteUtil.toHexString(XORContent(ByteUtil.hex2Bin(redom),ByteUtil.hex2Bin(ff)));
//		String keyA8 = ByteUtil.toHexString(DESUtil.tripleDESEncrypt(desKey, ByteUtil.hex2Bin(yhss)));
//		//System.out.println(keyA8);
//		
//		String key = keyP8+keyA8;//组装密钥
//		System.out.println("key:"+key);
//		
//		//bit5 = ByteUtil.toHexString(ME30DataDecode.getDecodeKey(key, bit5));
//		desKey = new DESKey(ByteUtil.hex2Bin(key));

        bit5 = ByteUtil.toHexString(DESUtil.tripleDESDecrypt(desKey, bit5.getBytes("UTF-8")));
        System.out.println(bit5);//磁道数据 打印


        return bit5;
    }

    /**
     * 异或
     *
     * @param content1
     * @param content2
     * @return
     */
    public static byte[] XORContent(byte[] content1, byte[] content2) {
        int i = 0;
        //byte []sOutMAC =new byte[8];
        byte[] res = new byte[8];
        for (i = 0; i < 8; i++) {
            res[i] = (byte) (content1[i] ^ content2[i]);
        }
        return res;

    }

    public static void main(String[] args) throws Exception {
//		decryptTrace2("6217730700097783=2301E498AB0AC2F9ADA0");
//		String ss = ByteUtil.toHexString(ME30DataDecode.getDecodeKey("F75B40DE00D133D3DDE7A2C1CAA82D29", "7B8A564EB304A0964CD92A69AC53C1A6456619AA9A39087F"));
//		System.out.println(ss);

        //获得 密钥前八位   用磁道密钥对8字节随机数进行加密，加密的结果作为密钥的左8字节。
//		String tackKey = "000102030405060708090a0b0c0d0e";
//		String redom = "C386A154000000BB";
//		String tackKey = "3F9E84CAC9A53156081F4ADE12E4CAF1";
//		String redom = "58840DEDFF313233";
//		DESKey desKey = new DESKey(ByteUtil.hex2Bin(tackKey));
//		String keyP8 = ByteUtil.toHexString(DESUtil.tripleDESEncrypt(desKey, ByteUtil.hex2Bin(redom)));
//		System.out.println(keyP8);
//		
//		//后八位 异或
//		String ff = "FFFFFFFFFFFFFFFF";
//		String yhss = ByteUtil.toHexString(XORContent(ByteUtil.hex2Bin(redom),ByteUtil.hex2Bin(ff)));
//		String keyA8 = ByteUtil.toHexString(DESUtil.tripleDESEncrypt(desKey, ByteUtil.hex2Bin(yhss)));
//		System.out.println(keyA8);

//		String[] a = decryptTrace2_aic("C62B8F7DFF313233","36B9002DD8A00AAC02E08E5841DD6A506C6FFFCC4C1087E7283E0A36B56EA8B380B8978F45D1A5A74E33D9BF4AA54E1F5A325FF9B0CB16841B7B5871A3C4CCA96933B7EF5DB69E299C25B12CDA63AA38");
//		String[] a = decryptTrace2_aic("2ED922FBFF313233","1D6E73B527F3C68EE83911B87BCC0912998CF83F1DDCB2E2C87246896D5BF26ADEEF1BE6A05D94666835E7AF14A64309CF861581F85B57B84E8B714BB509F462998CF83F1DDCB2E2");
//		System.out.println(a[0]);
//		System.out.println(a[1]);

        String bit55 = "C56E1BCFB8503996E4F4F2B84EC9B9C85E947E5E293DF263AD80628CA52F8001FEEFE924E9852D006C6888125C8EA04ED7B663B0C34D3F959E6E9970810AADD0844E7BA2689F1A0046627C0069F56773CECF21E7EE3A560D0DA052CAC2C5045330A3F3E22CC2CF9CB8FFF58FD8157EDC70D4BACFE2929F4414B8199B4758014DD5950525C601E73236EB722713E35FED7ACF9F67D0FE114A2410A5C9";
        decryptBt55_aic("23DDA5AEFF313233", bit55);

//		decryptTrace2_aic("","63121FAB8DE9B4BF26BC70F7ABDEA4D312F82072B972CDD4");
    }

}
